package com.atguigu.spring.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Order(3)
@Aspect
@Component
public class TxAspect {

    @Around("com.atguigu.spring.pointcut.MyPointCut.pointCutExpression()")
    public Object doTx(ProceedingJoinPoint joinPoint) {

        // 1、准备工作
        // [1]获取目标方法的方法名
        String methodName = joinPoint.getSignature().getName();

        // [2]获取外界间接调用目标方法时传入的实参数组
        Object[] args = joinPoint.getArgs();

        // 2、try {...} catch(Exception e) {} finally{}
        try {
            // 核心操作之前
            System.out.println("[环绕通知][开启事务]" + methodName + " 入参列表：" + Arrays.asList(args));

            // 所有操作的核心：调用目标方法
            Object targetReturnValue = joinPoint.proceed(args);

            // 核心操作成功
            System.out.println("[环绕通知][提交事务]" + methodName + " 返回值：" + targetReturnValue);

            // 把目标方法的返回值，返回给外界调用者
            return targetReturnValue;
        } catch (Throwable e) {

            // 核心操作失败
            System.out.println("[环绕通知][回滚事务]" + methodName + " 异常信息：" + e.getMessage());

            throw new RuntimeException(e);
        } finally {
            // 核心操作结束
            System.out.println("[环绕通知][释放资源]" + methodName);
        }
    }

}
